package com.example;

import com.example.common.filter.XssFilter;
import com.example.common.security.expression.AuthorizeConfigManger;
import com.example.common.security.filter.MyValidateCodeFilter;
import com.example.common.security.session.ExpiredSessionStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;

/**
 * @program: springsecurity-study
 * @description: SpringScurity配置类
 * @author: ChenZhiXiang
 * @create: 2019-07-25 21:25
 **/
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${login.page}")
    private String loginPage;

    /** 登录成功处理器 */
    @Autowired
    private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

    /** 登录失败处理器 */
    @Autowired
    private AuthenticationFailureHandler myAuthenticationFailureHandler;

    /** 退出登录处理器 */
    @Autowired
    private LogoutSuccessHandler myLogoutSuccessHandler;

    /** 记住我数据层实现，对记住我的信息入库 */
    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    /** UserDetailsService实现类 */
    @Autowired
    private UserDetailsService myUserDetailsServiceImpl;

    @Autowired
    private AuthorizeConfigManger authorizeConfigManger;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /* 引入验证码过滤器 **/
        MyValidateCodeFilter myValidateCodeFilter = new MyValidateCodeFilter();
        myValidateCodeFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler);

        /** 引入敏感词过滤器 */
        XssFilter xssFilter = new XssFilter();

        // 关闭跨站防护
            http.csrf().disable();

            http.addFilterBefore(myValidateCodeFilter, UsernamePasswordAuthenticationFilter.class)
                    .addFilterBefore(xssFilter, SecurityContextPersistenceFilter.class)
                .formLogin()
                    .loginPage("/authentication/require") // 当需要验证跳到哪里
                    .loginProcessingUrl("/szqy/login")
                    .successHandler(myAuthenticationSuccessHandler)
                    .failureHandler(myAuthenticationFailureHandler)
                .and()
                .rememberMe()
                    .tokenRepository(persistentTokenRepository) //记住我数据层实现
                    .tokenValiditySeconds(3600) //记住我过期时间
                    .userDetailsService(myUserDetailsServiceImpl) // 记住我用myUserDetailsServiceImpl做登录
                .and()
                .logout()
                    .permitAll()
                    .invalidateHttpSession(true)
                    .logoutUrl("/signLogout")
                    .logoutSuccessHandler(myLogoutSuccessHandler)
                    .deleteCookies("JSESSIONID")
                .and()
                .sessionManagement()
                    .invalidSessionUrl("/session/invalid") // session过期处理的接口
                    .maximumSessions(1) // 一个用户只能有一个session
                    .expiredSessionStrategy(new ExpiredSessionStrategy());
//                .and()
//                .and()
//                .authorizeRequests() //开启登录配置
//                    .antMatchers("/authentication/require").permitAll() //表示不需要登录就可以访问
//                    .antMatchers(loginPage).permitAll()
//                    .antMatchers("/images/captcha").permitAll()
//                    .antMatchers("/session/invalid").permitAll() // session失效的访问地址
//                    .antMatchers("/favicon.ico").permitAll() //表示不需要登录就可以访问
//                    .antMatchers("/add").hasRole("ADMIN")
//                    .anyRequest().authenticated(); // 表示剩下的登录就可以访问
                authorizeConfigManger.config(http.authorizeRequests());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 解决静态资源被拦截的问题
        web.ignoring().antMatchers("/global/**");
    }
}
